import { ref, onMounted, onUnmounted, Ref } from 'vue';

interface PollingOptions {
  interval: number; // 轮询间隔(ms)
  maxRetries?: number; // 最大重试次数
  onError?: (error: Error) => void; // 错误处理函数
  immediate?: boolean; // 是否立即执行
}

/**
 * 轮询功能的自定义Hook
 * @param fn 要轮询执行的函数
 * @param options 轮询选项
 * @returns 包含控制轮询的方法和状态
 */
function usePolling<T>(fn: () => Promise<T>, options: PollingOptions): {
  isPolling: Ref<boolean>;
  data: Ref<T | null>;
  error: Ref<Error | null>;
  retries: Ref<number>;
  start: () => void;
  stop: () => void;
  restart: () => void;
} {
  const { interval, maxRetries = Infinity, onError, immediate = true } = options;
  const isPolling = ref(false);
  const retries = ref(0);
  const data = ref<T | null>(null);
  const error = ref<Error | null>(null);
  const timerId = ref<number | null>(null);

  // 执行轮询任务
  const executePoll = async (): Promise<void> => {
    if (retries.value >= maxRetries) {
      stop();
      return;
    }

    try {
      const result = await fn();
      data.value = result;
      error.value = null;
      retries.value = 0; // 成功后重置重试次数
    } catch (err) {
      error.value = err as Error;
      retries.value += 1;
      if (onError) {
        onError(err as Error);
      }
    }

    if (isPolling.value) {
      timerId.value = window.setTimeout(executePoll, interval);
    }
  };

  // 开始轮询
  const start = (): void => {
    if (!isPolling.value) {
      isPolling.value = true;
      executePoll();
    }
  };

  // 停止轮询
  const stop = (): void => {
    isPolling.value = false;
    if (timerId.value) {
      window.clearTimeout(timerId.value);
      timerId.value = null;
    }
  };

  // 重启轮询
  const restart = (): void => {
    stop();
    start();
  };

  // 组件挂载时
  onMounted(() => {
    if (immediate) {
      start();
    }
  });

  // 组件卸载时
  onUnmounted(() => {
    stop();
  });

  return {
    isPolling,
    data: data as Ref<T | null>,
    error,
    retries,
    start,
    stop,
    restart
  };
}

export default usePolling;